package org.eenie.hookui.utils

import dalvik.system.DexFile
import java.lang.reflect.Field
import java.util.*


object OkHttpUtils {

    private var classNameList = mutableListOf<String>()

    fun getAllClassName(mLoader: ClassLoader): MutableList<String> {
        classNameList.clear()
        try {
            //系统的 classloader是 Pathclassloader需要 拿到他的 父类 BaseClassloader才有 pathList
            val pathListField: Field = Objects.requireNonNull(mLoader::class.java.superclass).getDeclaredField("pathList")
            pathListField.isAccessible = true
            val dexPathList: Any = pathListField.get(mLoader)
            val dexElementsField: Field = dexPathList.javaClass.getDeclaredField("dexElements")
            dexElementsField.isAccessible = true
            val dexElements = dexElementsField.get(dexPathList) as Array<*>
            for (i in dexElements.indices) {
                val dexFileField: Field = dexElements[i]!!.javaClass.getDeclaredField("dexFile")
                dexFileField.isAccessible = true
                val dexFile = dexFileField.get(dexElements[i]) as DexFile
                getDexFileClassName(dexFile)
            }
        } catch (e: NoSuchFieldException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        }
        return classNameList
    }

    private fun getDexFileClassName(dexFile: DexFile) {
        //获取df中的元素  这里包含了所有可执行的类名 该类名包含了包名+类名的方式
        val enumeration: Enumeration<String> = dexFile.entries()
        while (enumeration.hasMoreElements()) { //遍历
            val className: String = enumeration.nextElement()
            if (className.contains("okhttp3")) { //在当前所有可执行的类里面查找包含有该包名的所有类
                classNameList.add(className)
            }
        }
    }


}